/*
  请求模块
*/
import axios from 'axios'
import store from '@/store/'
import JSONbig from 'json-bigint'
import router from '@/router/'
import { Toast } from 'vant'

const request = axios.create({
  baseURL: 'http://toutiao.itheima.net/',
  transformResponse: [function (data) {
    try {
      return JSONbig.parse(data)
    } catch (err) {
      console.log('转换失败', err)
      return data
    }
  }]
})

const requestToken = axios.create({
  baseURL: 'http://toutiao.itheima.net/'
})

// 请求拦截器
request.interceptors.request.use(function (config) {
  const { user } = store.state
  if (user) {
    // 如果用户已登录，统一给接口设置 token 信息
    config.headers.Authorization = `Bearer ${user.token}`
  }
  return config
}, function (error) {
  return Promise.reject(error)
})

// 响应拦截器
// 添加响应拦截器
request.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response
}, async function (error) {
  // 对响应错误做点什么
  const status = error.response.status
  if (status === 400) {
    // 客户端请求参数异常
    Toast.fail('客户端请求参数异常')
  } else if (status === 401) {
    // token无效
    // 如果没有 user 或 user.token 直接跳转去重新登录
    Toast.fail('请重新登录')
    const { user } = store.state
    if (!user || !user.token) {
      return redirectLogin()
    }

    // 使用 refresh_token 重新获取 token
    try {
      const data = await requestToken({
        method: 'PUT',
        url: 'v1_0/authorizations',
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })

      // 拿到token 后重新放到容器内
      user.token = data.data.data.token
      store.commit('setUser', user)
      // 把失败的请求重新发过去（调用 request，并使用请求拦截器）
      return request(error.config)
    } catch (error) {
      return redirectLogin()
    }
  } else if (status === 403) {
    // 没有权限操作
    Toast.fail('没有权限操作')
  } else if (status >= 500) {
    // 服务器端异常，请稍后重试
    Toast.fail('服务器端异常，请稍后重试')
  }
  return Promise.reject(error)
})

function redirectLogin () {
  router.replace({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

// 导出
export default request
